package vue.panneau2.modele;

import java.util.ArrayList;
import java.util.List;

import modele.Equation2D;
import modele.FonctionAOptimiser2D;

import vue.panneau2.modele.exception.FonctionObjectifDejaParametreeException;
import vue.panneau2.modele.exception.IndiceIncorrectException;
import vue.panneau2.modele.exception.MauvaiseDimensionException;
import vue.panneau2.modele.util.Equation;
import vue.panneau2.modele.util.Simplexe;

public class ModelePanneau2 {
	/**
	 * Le probleme de programmation lineaire qui sera resolu par la methode du simplexe.
	 */
	private Simplexe problemeLineaire;
	/**
	 * Le numero d'etape courant dans la progression de l'algorithme
	 */
	private int numEtapeCourant = -1;
	
	/**
	 * Cree un probleme lineaire qui pourra etre resolu par la methode du simplexe.
	 * @param Dimension de la matrice : fixe le nombre de variables
	 * de base que la matrice pourra contenir.
	 */
	public void creerProblemeLineaire(int dimension) {
		problemeLineaire = new Simplexe(dimension);
	}
	
	/**
	 * Cree un probleme lineaire qui pourra etre resolu par la methode du simplexe.
	 * On nomme ici directement les variables par l'intermediaire de la collection
	 * nomVariables.
	 * @param Dimension de la matrice : fixe le nombre de variables
	 * de base que la matrice pourra contenir.
	 * @param nomVariables Une collection de noms indiquant les noms attribues
	 * aux variables de base.
	 */
	public void creerProblemeLineaire(int dimension, ArrayList<String> nomVariables) {
		problemeLineaire = new Simplexe(dimension, nomVariables);
	}
	
	/**
	 * Permet de recuperer le probleme courant de programmation lineaire.
	 * @return Le probleme de programmation lineaire courant encapsule dans
	 * un objet de type Simplexe.
	 */
	public Simplexe getProblemeLineaire() {
		return problemeLineaire;
	}
	
	/**
	 * Permet de mettre en place un systeme d'equation a deux dimensions
	 * a partir d'une liste d'equations 2D et d'une fonction a optimiser 2D
	 * passee en parametre.
	 * Assure leur conversion vers le systeme d'equations generiques propre a
	 * l'algorithme du simplexe.
	 * @param listeEquation2D La liste d'equations 2D qui sera mise en place pour une
	 * resolution ulterieure par la methode du simplexe.
	 * @param fctAOptimiser La fonction a optimiser ulterieurement
	 * par l'algorithme du simplexe.
	 */
	public void setSystemeEquation2D(List<Equation2D> listeEquation2D, FonctionAOptimiser2D fctAOptimiser) {
		try 
		{
			//Creation ou reinitialisation du systeme d'equation
			creerProblemeLineaire(2);
			
			//Reglage par défaut du libellé des variables
			getProblemeLineaire().setNomVariable(0, "X1");
			getProblemeLineaire().setNomVariable(1, "X2");
			
			//Ajout de toutes les equations 2D
			for (Equation2D eq : listeEquation2D) {
				
				System.out.println("don a la zone 2 de l equation :"+eq.getX1()+","+eq.getX2()+","+eq.getPartieDroite());
				
				Equation eqGene = new Equation(2, false, Equation.INF_OU_EGAL);
				eqGene.setCoefficient(0, eq.getX1());
				eqGene.setCoefficient(1, eq.getX2());
				eqGene.setPartieDroite(eq.getPartieDroite());
				getProblemeLineaire().ajouterEquation(eqGene);
			}
			
			//Ajout de la fonction objectif
			if (fctAOptimiser != null) {
				Equation eqGene = new Equation(2, true, Equation.INF_OU_EGAL);
				eqGene.setCoefficient(0, fctAOptimiser.getX1());
				eqGene.setCoefficient(1, fctAOptimiser.getX2());
				getProblemeLineaire().ajouterEquation(eqGene);
				
				
//				System.out.println("matrice initiale :");
//				for (String s : getProblemeLineaire().getMatriceEtape(0)) {
//					System.out.println(s);
//				}
			}
			
			
		}
		catch (IndiceIncorrectException e) 
		{
			e.printStackTrace();
		}
		catch (FonctionObjectifDejaParametreeException e) 
		{
			e.printStackTrace();
		}
		catch (MauvaiseDimensionException e)
		{
			e.printStackTrace();
		}
	}
	
	/**
	 * Permet d'acceder au numero d'etape courant (au niveau du programme et de l'algorithme).
	 * @return Un entier correspondant au numero de l'etape courante.
	 */
	public int getNumEtapeCourant() {
		return numEtapeCourant;
	}

	/**
	 * Permet de changer le numero d'etape courant (au niveau du programme et de l'algorithme).
	 * @param numEtapeCourant Un entier correspondant au numero de la nouvelle etape courante.
	 */
	public void setNumEtapeCourant(int numEtapeCourant) {
		this.numEtapeCourant = numEtapeCourant;
	}
}
